package com.jueyunqi.vertx;

import com.jueyunqi.service.ExportService;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Handler;
import io.vertx.core.eventbus.Message;
import org.springframework.context.ApplicationContext;

/**
 * Created by zhongwen on 2018/3/22.
 */
public class SpringVerticle extends AbstractVerticle {

    private ExportService service;

    public static final String PRINT_MSG_SERVICE_ADDRESS = "print_msg_service_address";

    public static final String GET_MSG_SERVICE_ADDRESS = "get_msg_service_address";

    public SpringVerticle(ApplicationContext ctx) {
        // 从spring上下文获取service
        this.service = ctx.getBean(ExportService.class);
    }

    @Override
    public void start() throws Exception {
        // 唤起事件总线，注册一个事件处理者，或者直译叫事件消费者
        vertx.eventBus().<String> consumer(PRINT_MSG_SERVICE_ADDRESS)
                .handler(msg -> {
                    // 获取事件内容后，调用service服务
                    // 这里是非阻塞式调用
                    service.run("Asynchronous call dubbo service!!!");
                    msg.reply("success");
                });

        vertx.eventBus().<String> consumer(GET_MSG_SERVICE_ADDRESS, printMsg());
    }

    // 模拟dubbo服务要从后台数据库获取数据，所以这里就是vert.x中的阻塞式调用
    // vert.x中规定，所有调用不可以阻塞其eventloop，所以当有数据库调用、thread.sleep等可能会阻塞线程的服务调动时
    // 需要使用vertx接口中的阻塞式调用接口
    private Handler<Message<String>> printMsg() {
        return msg -> {
            System.out.println("bus msg body is:" + msg.body());
            // 阻塞式接口调用
            vertx.<String> executeBlocking(future -> {
                // 通过future等待调用返回结果
                String dubboMsg = "";
                try {
                    dubboMsg = this.service.doRun("vertx run ...");
                } catch (Exception e) {
                    e.printStackTrace();
                    future.fail(e);
                }
                // 把结果放到result中
                future.complete(dubboMsg);
            }, result -> {
                // 判断接口调用结果，成功的话讲结果放到事件总线的msg中传递给server端展示
                if (result.succeeded()) {
                    System.out.println("msg from dubbo service is: "
                            + result.result());
                    msg.reply(result.result());
                }
                if (result.failed()) {
                    msg.fail(400, result.cause().getMessage());
                }
            });
        };
    }

}
